package com.shop.servlet;

import com.google.gson.Gson;
import com.shop.bean.Product;
import com.shop.bean.CustomField;
import com.shop.dao.ProductDao;
import com.shop.dao.CustomFieldDao;
import org.bson.types.ObjectId;
import org.bson.Document;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;

@WebServlet("/product/*")
public class ProductServlet extends HttpServlet {
    private ProductDao productDao = new ProductDao();
    private CustomFieldDao customFieldDao = new CustomFieldDao();
    private Gson gson = new Gson();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        String path = req.getPathInfo();
        if ("/list".equals(path)) {
            String searchName = req.getParameter("name");
            List<Product> products = productDao.findAll();
            
            if (searchName != null && !searchName.trim().isEmpty()) {
                List<Product> filteredProducts = new ArrayList<>();
                for (Product product : products) {
                    if (product.getName().toLowerCase().contains(searchName.toLowerCase())) {
                        filteredProducts.add(product);
                    }
                }
                products = filteredProducts;
            }
            
            List<Document> result = new ArrayList<>();
            for (Product product : products) {
                Document doc = new Document();
                doc.put("_id", product.getId().toHexString());
                doc.put("name", product.getName());
                doc.put("price", product.getPrice());
                doc.put("stock", product.getStock());
                doc.put("description", product.getDescription());
                doc.put("customFields", product.getCustomFields());
                result.add(doc);
            }
            sendJsonResponse(resp, result);
        } else if ("/fields".equals(path)) {
            List<CustomField> fields = customFieldDao.findAll();
            sendJsonResponse(resp, fields);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        String path = req.getPathInfo();
        resp.setContentType("application/json");
        resp.setCharacterEncoding("UTF-8");
        
        if ("/add".equals(path)) {
            Product product = new Product();
            product.setName(req.getParameter("name"));
            product.setPrice(Double.parseDouble(req.getParameter("price")));
            product.setStock(Integer.parseInt(req.getParameter("stock")));
            product.setDescription(req.getParameter("description"));
            String customFieldsJson = req.getParameter("customFields");
            if (customFieldsJson != null && !customFieldsJson.isEmpty()) {
                Map<String, Object> customFields = gson.fromJson(customFieldsJson, Map.class);
                product.setCustomFields(customFields);
            }
            productDao.insert(product);
            sendJsonResponse(resp, "{\"success\": true}");
        } else if ("/update".equals(path)) {
            String id = req.getParameter("id");
            System.out.println("Attempting to update product with id: " + id);
            try {
                Product product = new Product();
                product.setId(new ObjectId(id));
                product.setName(req.getParameter("name"));
                product.setPrice(Double.parseDouble(req.getParameter("price")));
                product.setStock(Integer.parseInt(req.getParameter("stock")));
                product.setDescription(req.getParameter("description"));
                String customFieldsJson = req.getParameter("customFields");
                if (customFieldsJson != null && !customFieldsJson.isEmpty()) {
                    Map<String, Object> customFields = gson.fromJson(customFieldsJson, Map.class);
                    product.setCustomFields(customFields);
                }
                productDao.update(product);
                sendJsonResponse(resp, "{\"success\": true}");
            } catch (IllegalArgumentException e) {
                System.out.println("Invalid ObjectId format or number format: " + e.getMessage());
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                sendJsonResponse(resp, "{\"success\": false, \"message\": \"Invalid data format\"}");
            }
        } else if ("/delete".equals(path)) {
            String id = req.getParameter("id");
            System.out.println("Attempting to delete product with id: " + id);
            try {
                productDao.delete(id);
                sendJsonResponse(resp, "{\"success\": true}");
            } catch (IllegalArgumentException e) {
                System.out.println("Invalid ObjectId format: " + e.getMessage());
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                sendJsonResponse(resp, "{\"success\": false, \"message\": \"Invalid ID format\"}");
            }
        } else if ("/field/add".equals(path)) {
            CustomField field = new CustomField();
            field.setName(req.getParameter("name"));
            field.setType(req.getParameter("type"));
            customFieldDao.save(field);
            sendJsonResponse(resp, "{\"success\": true}");
        } else if ("/field/delete".equals(path)) {
            String name = req.getParameter("name");
            customFieldDao.delete(name);
            sendJsonResponse(resp, "{\"success\": true}");
        }
    }

    private void sendJsonResponse(HttpServletResponse resp, Object data) throws IOException {
        resp.setContentType("application/json");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.print(gson.toJson(data));
        out.flush();
    }
} 